package com.xtyhz.server.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import cn.hutool.captcha.generator.RandomGenerator;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xtyhz.mapper.UserMapper;
import com.xtyhz.model.R;
import com.xtyhz.pojo.constant.JwtConstant;
import com.xtyhz.pojo.constant.RedisConstant;
import com.xtyhz.pojo.dto.LoginDto;
import com.xtyhz.pojo.User;
import com.xtyhz.server.UserService;
import com.xtyhz.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private UserMapper userMapper;

    @Override
    public R<Map<String,String>> getCode() {
        try {
            ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(100, 30, 4, 0);
            RandomGenerator randomGenerator = new RandomGenerator("0123456789",4);
            shearCaptcha.setGenerator(randomGenerator);
            String code = shearCaptcha.getCode();

            //转为base64的形式给前端
            String base64 = shearCaptcha.getImageBase64();

            Map<String,String> map = new HashMap<>();
            map.put("img",base64);
            String uuid = UUID.randomUUID().toString();
            map.put("uuid", uuid);
            stringRedisTemplate.opsForValue().set(RedisConstant.LOGIN_CODE+uuid,code,60, TimeUnit.SECONDS);

            return R.ok(map);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("获取验证码失败");
        }
    }

    @Override
    public R<Map<String, String>> login(LoginDto loginDto) {
        //账号密码判断
        if (!verificationString(loginDto.getUsername())) {
            return R.fail("账号密码错误");
        }

        if (!verificationString(loginDto.getPassword())) {
            return R.fail("账号密码错误");
        }
        if (!verificationString(loginDto.getCode())) {
            return R.fail("请输入验证码");
        }
        if (!verificationString(loginDto.getUuid())) {
            return R.fail("请重新输入验证码");
        }

        //验证code:Redis验证
        String code = stringRedisTemplate.opsForValue().get(RedisConstant.LOGIN_CODE + loginDto.getUuid());
        if (code == null || !code.equals(loginDto.getCode())) {
            return R.fail("验证码已过期或者验证码错误");
        }

        User user = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, loginDto.getUsername()));
        if (user == null){
            return R.fail("用户不存在");
        }

        if (!user.getPassword().equals(loginDto.getPassword())){
            return R.fail("密码错误");
        }

        //TODO 继续添加登录逻辑

        //生成认证token和刷新token方法
        Map<String, String> map = createTokens(user.getUserId().toString());
        //用户信息给前端
        user.setPassword(null);
        map.put("userInfo", JSONUtil.toJsonStr(user));

        return R.ok(map);
    }

    /**
     * 刷新token方法
     * @param refreshToken 刷新token
     * @return 返回两个token
     */
    @Override
    public R<Map<String, String>> refreshToken(Map<String,String> refreshToken) {
        String refreshToken1 = refreshToken.get("refreshToken");
        System.out.println(refreshToken);
        //解析token,拿token中的id
        String userId = JwtUtils.getUsernameFromToken(refreshToken1);

        //生成认证token和刷新token方法
        Map<String, String> map = null;
        if (userId != null) {
            map = createTokens(userId);
        }
        System.out.println(map);

        return R.ok(map);
    }

    /**
     * 查询所有管理端用户
     * @param page 当前页
     * @param size 每页大小
     * @param nickname 用户姓名
     * @param email 邮箱
     * @param phone 电话
     * @return 返回用户集合
     */
    @Override
    public R<List<User>> list(Integer page, Integer size, String nickname, String email, String phone) {
        if (page == null || page == 0 && size == null || size == 0) {
            return R.fail("参数错误");
        }

        List<User> userList = null;
        try {
            userList = userMapper.userList(page,size,nickname,email,phone);
            if (userList == null){
                return R.ok();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("内部服务器错误");
        }

        return R.ok(userList);
    }

    /**
     * 用户添加
     * @param user 用户信息:用户账号,用户姓名,用户密码,电话,邮箱
     * @return 返回是否成功
     */
    @Override
    public R<String> add(User user) {
        if (!verificationString(user.getNickname()) || !verificationString(user.getUsername()) || !verificationString(user.getPassword())){
            return R.fail("参数错误");
        }
        try {
            user.setCreateTime(new Date());
            userMapper.addUser(user);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("内部服务器错误,请及时反馈");
        }
        return R.ok("添加成功");
    }

    /**
     * 修改用户
     * @param user 用户信息
     * @return 返回是否成功
     */
    @Override
    public R<String> update(User user) {
        if (!verificationString(user.getNickname()) || !verificationString(user.getUsername())){
            return R.fail("参数错误");
        }
        try {
            userMapper.updateUser(user);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("内部服务器错误,请及时反馈");
        }
        return R.ok("修改成功");
    }

    /**
     *
     * @param userId 用户Id
     * @return 返回是否成功
     */
    @Override
    public R<String> delete(Integer userId) {
        if (userId == null || userId == 0){
            return R.fail("参数错误");
        }


        try {
            userMapper.deleteUserById(userId);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("内部服务器错误,请及时反馈");
        }
        return R.ok("删除成功");
    }

    /**
     * 生成两个token
     * @param uid 用户id
     * @return 返回两个token
     */
    private Map<String, String> createTokens(String uid) {
        //认证token
        String authenticationToken = JwtUtils.generateToken(uid, JwtConstant.AUTHENTICATION_TOKEN);

        //刷新token
        String refurbishToken = JwtUtils.generateToken(uid, JwtConstant.REFURBISH_TOKEN);

        //把token存储map集合
        Map<String,String> map = new HashMap<>();
        map.put("authenticationToken",authenticationToken);
        map.put("refurbishToken",refurbishToken);

        return map;
    }

    /**
     * String类型验证
     * @param param String参数
     * @return 返回是否为空
     */
    private Boolean verificationString(String param) {
        if (StringUtils.isBlank(param)){
            return false;
        }
        return !param.contains(" ");
    }
}
